﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using Component.Mesh;
using Component.Tools;
using Component.Trains;
using Component.UI;
using UnityEngine;
using Object = UnityEngine.Object;
using Random = UnityEngine.Random;

namespace Component.Track
{
    public class Line
    {
        
        private static readonly QueuePool<DrawLineTools> LinePool = new QueuePool<DrawLineTools>(Resources.Load<GameObject>("Prefabs/Line"), new GameObject("lines").transform);
        private static readonly QueuePool<DrawLineTools> EndLinePool = new QueuePool<DrawLineTools>(Resources.Load<GameObject>("Prefabs/End"), new GameObject("endLines").transform);

        private static readonly Dictionary<int, DrawLineTools> LineMap = new Dictionary<int, DrawLineTools>();
        private static readonly List<DrawLineTools> EndLines = new List<DrawLineTools>();
        /// <summary>
        /// 创建DrawMeshTools
        /// </summary>
        /// <returns></returns>
        public static DrawLineTools CreateLine(bool add = true)
        {
            DrawLineTools drawLineTools = LinePool.GetInstance();
            if(add)
                LineMap.Add(drawLineTools.gameObject.GetHashCode(), drawLineTools);
            return drawLineTools;
        }

        /// <summary>
        /// 连线终点
        /// </summary>
        /// <param name="node">结点</param>
        public static DrawLineTools CreateEnd(StationNode node)
        {
            DrawLineTools mesh = EndLinePool.GetInstance();
            node.SetLine(mesh);
            mesh.SetNode(node);
            EndLines.Add(mesh);
            return mesh;
        }
        
        /// <summary>
        /// 将临时线回收
        /// </summary>
        /// <param name="line">待回收的DrawLineTools</param>
        public static void ResetLine(DrawLineTools line)
        {
            Task task = new Task(line.ResetLine());
            task.Finished += manual =>
            {
                LineMap.Remove(line.gameObject.GetHashCode());
                LinePool.ResetInstance(line);
            };
        }


        /// <summary>
        /// 将临时线回收
        /// </summary>
        /// <param name="line">待回收的DrawLineTools</param>
        /// <param name="node">等待去线关系的点</param>
        public static void ResetLine(DrawLineTools line, StationNode node)
        {
            Task task = new Task(line.ResetLine());
            task.Finished += manual =>
            {
                LineMap.Remove(line.gameObject.GetHashCode());
                LinePool.ResetInstance(line);
                node.ClearLine();
            };
        }

        public static void ResetAllLine()
        {
            int[] instanceIds = LineMap.Keys.ToArray();
            for (int i = instanceIds.Length - 1; i >= 0 ; i--)
            {
                LinePool.ResetInstance(LineMap[instanceIds[i]]);
                LineMap.Remove(instanceIds[i]);
            }
            ResetAllEndLines();
        }

        public static void ResetEndLine(DrawLineTools line)
        {
            line.ClearNode();
            line.ClearMesh();
            EndLinePool.ResetInstance(line);
            EndLines.Remove(line);
        }

        public static void ResetAllEndLines()
        {
            for (int i = 0; i < EndLines.Count;)
            {
                ResetEndLine(EndLines[i]);
            }
        }

        public static void LineInvisible(int hashCode, Transform node)
        {
            if (LineMap.ContainsKey(hashCode))
            {
                LineMap[hashCode].LineInvisibleTask(node);
            }
        }

        public static LineData GetLineFollowData(int lindId)
        {
            return LineMap[lindId].LineData;
        }

        public static DrawLineTools GetLine(int hashcode)
        {
            return LineMap[hashcode];
        }

        public static bool CompareLineColor(int hashcode, Color color)
        {
            if (!LineMap.ContainsKey(hashcode))
            {
                return false;
            }
            return LineMap[hashcode].Color == color;
        }

        public static Color GetLineColor(int hashcode)
        {
            return LineMap[hashcode].Color;
        }
        /// <summary>
        /// 火车离开轨道
        /// </summary>
        /// <param name="hashCode"></param>
        /// <param name="node"></param>
        public static void RunWayLine(int hashCode, Transform node)
        {
            if (LineMap.ContainsKey(hashCode))
            {
                LineMap[hashCode].TrainRunWay(node);
            }
        }

        public static LineData LineData(int lineId)
        {
            LineData lineData = new LineData();
            DrawLineTools startLine = LineMap[lineId];
            DrawLineTools currentLine = LineMap[lineId];
            
            lineData += currentLine.LineData;
            
            StationNode leftNode = currentLine.GetNode();
            StationNode rightNode = currentLine.GetNode(leftNode);
            
            while (leftNode != null)
            {
                currentLine = leftNode.GetLine(currentLine);
                if (currentLine.gameObject.layer != LayerMask.NameToLayer("End"))
                {
                    lineData += currentLine.LineData;
                    leftNode = currentLine.GetNode(leftNode);
                }
                else
                {
                    leftNode = null;
                }
            }
            currentLine = startLine;
            while (rightNode != null)
            {
                currentLine = rightNode.GetLine(currentLine);
                if (currentLine.gameObject.layer != LayerMask.NameToLayer("End"))
                {
                    lineData += currentLine.LineData;
                    rightNode = currentLine.GetNode(rightNode);
                }
                else
                {
                    rightNode = null;
                }
            }

            return lineData;
        }
        
        
    }
}